import chardet from 'chardet';

const CED_ICONV_ENCODINGS = {
  'BIG5-CP950': 'big5',
  KSC: 'euckr',
  'ISO-2022-KR': 'euckr',
  GB: 'gb2312',
  ISO_2022_CN: 'gb2312',
  JIS: 'shiftjis',
  SJS: 'shiftjis',
  Unicode: 'utf8',

  // Map ASCII to UTF-8
  'ASCII-7-bit': 'utf8',
  ASCII: 'utf8',
  MACINTOSH: 'utf8'
};

// Byte Order Mark's to detect endianness and encoding.
const BOM_ENCODINGS = {
  utf8: [0xEF, 0xBB, 0xBF],
  utf16be: [0xFE, 0xFF],
  utf16le: [0xFF, 0xFE]
};

const checkSequence = (buffer, sequence) => {
  if (buffer.length < sequence.length) {
    return false;
  }
  return sequence.every((v, i) => v === buffer[i]);
};

/**
 * Guess the encoding from the buffer.
 *
 * @param {Buffer} buffer
 * @param {boolean} autoGuessEncoding
 * @returns {Encoding}
 */
export const guessEncoding = (buffer, autoGuessEncoding) => {
  let isBom = false;
  let encoding = 'utf8';

  // Detect UTF8- and UTF16-BOM encodings.
  for (const [key, value] of Object.entries(BOM_ENCODINGS)) {
    if (checkSequence(buffer, value)) {
      return { encoding: key, isBom: true };
    }
  }

  // Auto guess encoding, otherwise use UTF8.
  if (autoGuessEncoding) {
    // 使用 chardet 检测编码
    encoding = chardet.detect(buffer);
    if (CED_ICONV_ENCODINGS[encoding]) {
      encoding = CED_ICONV_ENCODINGS[encoding];
    } else if (encoding) {
      encoding = encoding.toLowerCase().replace(/-_/g, '');
    }
  }
  return { encoding, isBom };
};
